# apps/subjects/serializers.py
from rest_framework import serializers
from .models import Subject


class SubjectSerializer(serializers.ModelSerializer):
    """
    学科序列化器：用于列表、详情、创建、更新
    """
    parent_name = serializers.CharField(source='parent.name', read_only=True, help_text="父级学科名称")
    level_label = serializers.CharField(source='get_level_display', read_only=True, help_text="学科层级文本描述")
    has_children = serializers.BooleanField(read_only=True, help_text="是否有子学科")

    class Meta:
        model = Subject
        fields = [
            'id',
            'name',
            'code',
            'level',
            'level_label',
            'parent',
            'parent_name',
            'is_active',
            'sort_order',
            'has_children',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['created_at', 'updated_at']

    def validate(self, attrs):
        """
        自定义验证逻辑：
        - 一级学科不能有 parent
        - 二级学科必须有 parent
        - 禁止形成循环引用（如 A -> B -> A）
        """
        level = attrs.get('level', getattr(self.instance, 'level', None))
        parent = attrs.get('parent', getattr(self.instance, 'parent', None))

        if level == 1:
            if parent is not None:
                raise serializers.ValidationError("一级学科不能设置父级学科。")
        elif level == 2:
            if parent is None:
                raise serializers.ValidationError("二级学科必须选择一个父级学科。")
            if parent.level != 1:
                raise serializers.ValidationError("父级学科必须是一级学科。")
        else:
            raise serializers.ValidationError("学科层级只能是 1（一级）或 2（二级）。")

        # 检查循环引用（仅在创建或更新时检查）
        if parent and self.instance and self.instance == parent:
            raise serializers.ValidationError("学科不能将自己设为父级。")

        if parent and self.instance:
            # 检查是否间接形成环（例如 A -> B -> A）
            ancestor = parent.parent
            while ancestor:
                if ancestor == self.instance:
                    raise serializers.ValidationError("不能形成循环引用。")
                ancestor = ancestor.parent

        return attrs


class SubjectTreeSerializer(serializers.ModelSerializer):
    """
    学科树形结构序列化器：用于返回嵌套的学科树
    示例：一级学科下包含其所有二级学科
    """
    children = serializers.SerializerMethodField(help_text="子学科列表（二级学科）")

    class Meta:
        model = Subject
        fields = [
            'id',
            'name',
            'code',
            'level',
            'is_active',
            'sort_order',
            'children',
        ]

    def get_children(self, obj):
        """
        获取当前学科的子学科（仅限二级学科）
        """
        if obj.children.exists():
            return SubjectTreeSerializer(obj.children.filter(is_active=True), many=True).data
        return []

    def to_representation(self, instance):
        data = super().to_representation(instance)
        # 只显示激活状态的二级学科
        data['children'] = [child for child in data['children'] if child['is_active']]
        return data


class SubjectMinimalSerializer(serializers.ModelSerializer):
    """
    极简学科序列化器：用于下拉框、选项等场景
    """
    class Meta:
        model = Subject
        fields = ['id', 'name', 'code', 'level']